﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace Tomahawk.Resources.Reflection
{
    /// <summary>
    /// This class search and indexes all assemblies found on the application forlder
    /// </summary>
    public class AssemblyIndexer
    {

        #region "Singleton"

        private static AssemblyIndexer instance;

        public static AssemblyIndexer Instance { get { return instance; } }

        static AssemblyIndexer()
        {
            instance = new AssemblyIndexer();
        }

        #endregion

        /// <summary>
        /// Array with the application assemblies
        /// </summary>
        public Assembly[] Assemblies { get; private set; }

        /// <summary>
        /// Constructor
        /// </summary>
        public AssemblyIndexer()
        {
            this.fillAssembliesArray();
        }

        /// <summary>
        /// Index all application assemblies into a single array
        /// </summary>
        private void fillAssembliesArray()
        {
            //get the application executable directory
            System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(".\\");
            System.IO.FileInfo[] exeFiles = di.GetFiles("*.*");

            //create the assembly array
            this.Assemblies = new Assembly[exeFiles.Length];
            for (int i = 0; i < exeFiles.Length; i++) Assemblies[i] = null;

            int cnt = 0;
            foreach (System.IO.FileInfo fi in exeFiles)
            {
                if ((fi.Name.EndsWith(".exe") || fi.Name.EndsWith(".dll")))
                {
                    Assembly asm = Assembly.LoadFrom(fi.Name);
                    if (asm != null)
                    {
                        Assemblies[cnt] = asm;
                        cnt++;
                    }
                }
            }
        }

        /// <summary>
        /// Search a Type by name in all loaded assemblies
        /// </summary>
        public Type GetTypeFromAssemblies(string typeName)
        {
            Type retVal = null;
            foreach (Assembly asm in this.Assemblies)
            {
                if ((asm != null) && (retVal == null))
                {
                    Type testType = asm.GetType(typeName);
                    if (testType != null) retVal = testType;
                }
            }
            return retVal;
        }

    }

}
